package org.java.auth.handler;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.java.commons.vo.Result;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.access.AccessDeniedHandler;
import org.springframework.security.web.access.AccessDeniedHandlerImpl;
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
import org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

public class SmartHandler extends SavedRequestAwareAuthenticationSuccessHandler
        implements AuthenticationFailureHandler, AccessDeniedHandler {

    //负责转换json和Java对象
    private ObjectMapper objectMapper = new ObjectMapper();
    // 默认的访问拒绝处理器
    private AccessDeniedHandlerImpl defaultDeniedHandler = new AccessDeniedHandlerImpl();

    public SmartHandler(){
    }
    public SmartHandler(String errorPage){
        defaultDeniedHandler.setErrorPage(errorPage);
    }
    //登录失败
    @Override
    public void onAuthenticationFailure(HttpServletRequest httpServletRequest,
                                        HttpServletResponse httpServletResponse,
                                        AuthenticationException e)
            throws IOException, ServletException {

        //返回错误信息
        Result result = Result.error("登录失败：" + e.getLocalizedMessage());
        if (!this.sendJson(result,httpServletRequest,httpServletResponse)) {
            //返回HTML的时候，重定向到登录页面
            httpServletResponse.sendRedirect("./login");
        }
    }
    //登录成功
    @Override
    public void onAuthenticationSuccess(HttpServletRequest httpServletRequest,
                                        HttpServletResponse httpServletResponse,
                                        Authentication authentication)
            throws IOException, ServletException {
        Result result = Result.ok("登录成功");
        if (!this.sendJson(result,httpServletRequest,httpServletResponse)) {
            // 没有发送JSON，则执行保存的请求
            super.onAuthenticationSuccess(httpServletRequest, httpServletResponse, authentication);
        }
    }

    public boolean sendJson(Result result,HttpServletRequest httpServletRequest,
                             HttpServletResponse httpServletResponse) throws IOException {
        String accept = httpServletRequest.getHeader("Accept");
        //Accept请求头表示要求服务器返回什么类型的 数据
        if (accept != null && accept.startsWith("application/json")) {
            //把对象转换为json
            String json = objectMapper.writeValueAsString(result);
            httpServletResponse.setContentType("application/json;charset=UTF-8");
            httpServletResponse.getWriter().println(json);
            return true;
        } else {
           return false;
        }
    }

    @Override
    public void handle(HttpServletRequest request,
                       HttpServletResponse response,
                       AccessDeniedException e)
            throws IOException, ServletException {

        Result result = Result.error("访问被拒绝: " + e.getLocalizedMessage());
        response.setStatus(403);// 访问没有权限
        if (!this.sendJson(result, request, response)) {
            // 没有发送JSON的时候，使用默认的访问拒绝处理器
            defaultDeniedHandler.handle(request, response, e);
        }

    }
}

